package project.web_2.rest;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.util.JAXBSource;
import javax.xml.transform.Source;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;

import project.web_2.model.NoResumeFound;
import project.web_2.model.Resume;
import project.web_2.model.ResumeManager;
import project.web_2.model.ResumeNotFound;



/**
 * Serveur de l'application.
 * @author Anton KISSELEFF & Nicolas LETHUILLIER
 */
@WebServiceProvider
@ServiceMode(value=Service.Mode.MESSAGE)
public class ResumeServer implements Provider<Source> {
	
	// ATTRIBUTS
	
	@javax.annotation.Resource(type=Object.class)
	protected WebServiceContext wsContext;
	
	private ResumeManager resumeManager = new ResumeManager();
	
	private JAXBContext jc;
	
	// CONSTRUCTEURS
	
	public ResumeServer() {
		try {
            jc = JAXBContext.newInstance(ResumeManager.class,Resume.class,NoResumeFound.class);
            
        } catch(JAXBException je) {
            System.out.println("Exception " + je);
            throw new WebServiceException("Cannot create JAXBContext", je);
        }
		
		// Resume exemple
		Resume r = new Resume("Emple", "Ex");
		r.setObjective("Réussir le projet !");
		List<String> pro = new ArrayList<String>(); {
			pro.add("Stage de L3");
		}
		r.setProExperience(pro);
		List<String> scol = new ArrayList<String>(); {
			scol.add("L3 Info");
			scol.add("L2 Info");
			scol.add("L1 MIEEA");
		}
		r.setSchoolHistory(scol);
		
        resumeManager.addResume(r);
	}
	
	// REQUETES
	
    public Source invoke(Source source) {
    	
        try{
            MessageContext mc = wsContext.getMessageContext();
            String method = (String)mc.get(MessageContext.HTTP_REQUEST_METHOD);
		    if (method.equals("GET"))
	                return get(mc);
			if (method.equals("PUT"))
					return put(source, mc);
			throw new WebServiceException("Unsupported method: " +method);  
        } catch(JAXBException je) {
            throw new WebServiceException(je);
        }
    }
    
    // OUTILS

    /**
     * Ajoute une {@link Resume} à la liste des CV enregistrés.
     * @param source le CV transmis à enregistrer
     * @param mc le message envoyé
     * @return le {@link ResumeManager} actualisé
     * @throws JAXBException
     */
	private Source put(Source source, MessageContext mc) throws JAXBException {
		Unmarshaller u = jc.createUnmarshaller();
		Resume resume = (Resume) u.unmarshal(source);
		resumeManager.addResume(resume);
		return new JAXBSource(jc, resumeManager);
	}

	/**
	 * Retourne toutes les {@link Resume}s dont le nom correspond au message envoyé.
	 * Celui-ci peut être séparé en plusieurs mots-clés par le caractère &.
	 * Si le message est "all", la méthode affiche toutes les {@link Resume}s.
	 * Si le message est vide, aucune {@link Resume} n'est retournée.
	 * @param mc le message envoyé
	 * @return les {@link Resume}s correspondantes
	 * @throws JAXBException
	 */
	private Source get(MessageContext mc) throws JAXBException {
		String str = (String) mc.get(MessageContext.QUERY_STRING);
		if (str != null) {
			try {
				int id = Integer.parseInt(str);
				try {
					return new JAXBSource(jc, resumeManager.getResume(id));
				} catch(ResumeNotFound e) {
					return new JAXBSource(jc, new NoResumeFound());
				}
			} catch(NumberFormatException e) {
				return new JAXBSource(jc, resumeManager);
			}
		}
		return new JAXBSource(jc, resumeManager);
	}
	
	// MAIN

	public static void main(String args[]) {
	      Endpoint e = Endpoint.create( HTTPBinding.HTTP_BINDING, new ResumeServer());
	      e.publish("http://127.0.0.1:8080/");
	       // pour arrêter : e.stop();
	 }
}
